/**************************************************************************(C)*
 *
 *  This file is part of the GreenHills project
 *  Copyright (C) 2009  Tieto Corporation
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  Not for commmercial use. Only with Tieto permission.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************(C)*/
#pragma once

#include "core/iserver.h"
#include "gps/gpsfix.h"
#include "gps/gpsposition.h"

#include <QtCore/QTime>
#include <QtCore/QObject>

#include "clientcoredll.h"

namespace greenhills {
namespace core {
    class CMoveableRoomItem;
}}

namespace greenhills {
namespace client {
namespace core {

class CRoom;

/**
  * @brief Greenhills client object
  *
  * This class maintains most important part of greenhills client logic and
  * calls methods on CProxy object. Method of this class are mostly
  * called from GUI.
  */
class GH_CLIENTCORE_QT_CLASS CClient
    : public QObject, public greenhills::core::IServerListener
{
    Q_OBJECT

public:
    CClient();
    ~CClient();

public:
    std::string userName() const {return mUserName;}
    client::core::CRoom *room() const {return mRoom;}

public:
    bool isLoggedIn() const;
    bool isInRoom() const;

    bool connect(const QString &pHost);
    bool disconnect();

    bool login(const QString &pUsername, const QString &pPassword);
    bool logout();

    greenhills::core::IRoomItem *addLocalUser();
    greenhills::core::IRoomItem *addItem(const QString &pItemName,
            const greenhills::core::CItemType &pItemType);

    bool removeItem(greenhills::core::IRoomItem *pRoomItem);
    bool updateItem(greenhills::core::IRoomItem *pRoomItem);

    greenhills::core::CRoomId createRoom(const QString &pRoomName,
            const greenhills::core::CRoomType &pRoomType,
            const QString &pPassword);
    bool joinRoom(const greenhills::core::CRoomId &pRoomId,
            const QString &pPassword);
    bool leaveRoom();

public:
    virtual void itemAdded(const greenhills::core::CRoomId &pRoomId,
            const greenhills::core::CItemId &pItemId,
            const std::string &pItemName,
            const greenhills::core::CItemType &pItemType);
    virtual void itemUpdated(const greenhills::core::CRoomId &pRoomId,
            const greenhills::core::CItemId &pItemId,
            const unsigned char *pData, unsigned int pLength);
    virtual void itemRemoved(const greenhills::core::CRoomId &pRoomId,
            const greenhills::core::CItemId &pItemId);

public Q_SLOTS:
    void onGPGGAreceived(const QTime &time,
        const greenhills::gps::CGPSPosition &position,
        const greenhills::gps::CGPSFix &fix, int satelites, float hdop,
        float altitude, float geoidHeight, float dgpsUpdateDelay,
        int dgpsStationId);

    void onGPVTGreceived(float headingTrueNorth, float headingMagnetic,
        float speedInKnots, float speedInKilometers);

    void onSubmitPositionTimerFired();

Q_SIGNALS:
    void roomJoined();
    void roomLeft();
    void userLoggedIn();
    void userLoggedOut();

private:
    client::core::CRoom *mRoom;
    std::string mUserName;
    greenhills::core::CClientId mClientId;
    greenhills::core::CMoveableRoomItem *mLocalUser;
};

} //namespace core
} //namespace client
} //namespace greenhills
